package com.joysuch.wwyt.bp.service.impl;

import com.google.gson.Gson;
import com.joysuch.wwyt.bp.bean.BpProductionFacilityVideoBean;
import com.joysuch.wwyt.bp.bean.BpSystemVideoAddBean;
import com.joysuch.wwyt.bp.entity.BpProductionFacilityVideo;
import com.joysuch.wwyt.bp.entity.BpSystemVideo;
import com.joysuch.wwyt.bp.entity.dsl.QBpProductionFacilityVideo;
import com.joysuch.wwyt.bp.entity.dsl.QBpSystemVideo;
import com.joysuch.wwyt.bp.repository.BpProductionFacilityVideoDao;
import com.joysuch.wwyt.bp.repository.BpSystemVideoDao;
import com.joysuch.wwyt.bp.service.AlarmMessageService;
import com.joysuch.wwyt.bp.service.BpProductionFacilityVideoService;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.common.util.MapUtils;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.monitoringcenter.bean.CameraMonitoringBean;
import com.joysuch.wwyt.risk.entity.RiskDistrict;
import com.joysuch.wwyt.risk.repository.RiskDistrictDao;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.Assert;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import static com.joysuch.wwyt.bp.entity.dsl.QBpSystemVideo.bpSystemVideo;

/**
 * @author xsx
 * @version 1.0
 * @date 2022/10/12 11:40
 */
@Service
@Transactional
public class BpProductionFacilityVideoServiceImpl implements BpProductionFacilityVideoService {

    @Autowired
    private BpProductionFacilityVideoDao bpProductionFacilityVideoDao;

    @Autowired
    private BpSystemVideoDao bpSystemVideoDao;

    @Autowired
    private AlarmMessageService alarmMessageService;

    @Autowired
    private BpSystemVideoDao dao;

    @Autowired
    private RiskDistrictDao riskDistrictDao;

    @Override
    public ResultBean save(BpProductionFacilityVideoBean bean) {
        List<BpProductionFacilityVideo> list = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(bean.getSystemVideoIds())) {
            for (Long systemVideoId : bean.getSystemVideoIds()) {
                BpProductionFacilityVideo old = bpProductionFacilityVideoDao.findByDeviceFacilityIdAndSystemVideoId(bean.getDeviceFacilityId(), systemVideoId);
                if (old != null) {
                   return ResultBean.fail(101, "该监控视频已经绑定");
                }
            }
            int old=0;
            List<Long> oldList = bpProductionFacilityVideoDao.findByDeviceFacilityId(bean.getDeviceFacilityId());
            if (CollectionUtils.isNotEmpty(oldList)){
                old=oldList.size();
            }
            if ((old+bean.getSystemVideoIds().size())>10){
                return ResultBean.fail(101, "摄像头只能添加10个");
            }
            for (Long systemVideoId : bean.getSystemVideoIds()) {
                BpProductionFacilityVideo bpProductionFacilityVideo = new BpProductionFacilityVideo();
                bpProductionFacilityVideo.setSystemVideoId(systemVideoId);
                bpProductionFacilityVideo.setDeviceFacilityId(bean.getDeviceFacilityId());
                bpProductionFacilityVideo.setCreateBy(Context.getCurrentUserId());
                bpProductionFacilityVideo.setCreateTime(new Date());
                bpProductionFacilityVideo.setTenentId(Context.getCurrentTenantId());
                bpProductionFacilityVideo.setOrgCode(Context.getCurrentOrgCode());
                list.add(bpProductionFacilityVideo);
            }
            bpProductionFacilityVideoDao.saveAll(list);
        }

        return ResultBean.success(list);
    }

    @Override
    public Page<BpProductionFacilityVideoBean> page(Pageable pageable, Long deviceFacilityId) {

        QBpProductionFacilityVideo q = QBpProductionFacilityVideo.bpProductionFacilityVideo;
        Predicate predicate = null;
        if (deviceFacilityId != null) {
            predicate = ExpressionUtils.and(predicate, q.deviceFacilityId.eq(deviceFacilityId));
        }

        List<BpProductionFacilityVideoBean> beans = new ArrayList<>();
        Assert.notNull(deviceFacilityId, "deviceFacilityId cannot be null");
        pageable = PageDataUtils.addOrderByDesc(pageable, "id");
        Page<BpProductionFacilityVideo> all = bpProductionFacilityVideoDao.findAll(predicate, pageable);
        return PageDataUtils.convertPageData(all, new PageDataUtils.PageDataConvert<BpProductionFacilityVideoBean, BpProductionFacilityVideo>() {
            @Override
            public BpProductionFacilityVideoBean convert(BpProductionFacilityVideo video) {
                Optional<BpSystemVideo> byId = bpSystemVideoDao.findById(video.getSystemVideoId());
                BpProductionFacilityVideoBean bean = new BpProductionFacilityVideoBean();
                if (byId.isPresent()) {
                    BpSystemVideo bpSystemVideo =byId.get();
                    BeanUtils.copyProperties(video, bean);
                    if (bpSystemVideo != null) {
                        bean.setName(bpSystemVideo.getName());
                        bean.setCode(bpSystemVideo.getId());
                        bean.setVideoId(bpSystemVideo.getId());
                    }
                }
                return bean;
            }
        });

    }

    @Override
    public List<BpProductionFacilityVideoBean> findByDeviceFacilityId(Long deviceFacilityId) {
        List<BpProductionFacilityVideoBean> beans = new ArrayList<>();
        List<BpProductionFacilityVideo> list = bpProductionFacilityVideoDao.findListByDeviceFacilityId(deviceFacilityId);
        if (CollectionUtils.isNotEmpty(list)) {
            for (BpProductionFacilityVideo video : list) {
                BpProductionFacilityVideoBean bean = new BpProductionFacilityVideoBean();
                BpSystemVideo bpSystemVideo = bpSystemVideoDao.findById(video.getSystemVideoId()).get();
                BeanUtils.copyProperties(video, bean);
                if (bpSystemVideo != null) {
                    bean.setName(bpSystemVideo.getName());
                    bean.setCameraMonitoringBean(convertCamerasBean(bpSystemVideo));
                }
                beans.add(bean);
            }
        }
        return beans;
    }


    private CameraMonitoringBean convertCamerasBean(BpSystemVideo sv) {
        CameraMonitoringBean c = new CameraMonitoringBean();
        c.setId(sv.getId());
        // c.setArea(sv.getName());
        c.setName(sv.getName());
        c.setRtmp(sv.getRealTimeSite());
        //c.setStatus(0);
        MapUtils.ThreeDPoints threeDPoints = MapUtils.parse3DPointsFromJson(sv.getRegion());
        Gson gson = new Gson();
        MapUtils.SafetyPoints points = null;
        try {
            points = gson.fromJson(sv.getRegion(), MapUtils.SafetyPoints.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (points != null) {
            List<MapUtils.SafetyPoint> safetyPoints = points.getPoints();
            MapUtils.SafetyPoint point = MapUtils.calculateCenterPointZ(safetyPoints);
            c.setX(point.getX());
            c.setY(point.getY());
            c.setZ(point.getZ() == null ? 0.00 : point.getZ());
            c.setFloorId(String.valueOf(threeDPoints.getFloorId()));
        } else {
            MapUtils.WwytPoint point = MapUtils.parseSinglePoint(sv.getRegion());
            if (point != null && point.getX() != null && point.getY() != null) {
                c.setX(point.getX());
                c.setY(point.getY());
                c.setZ(point.getZ() == null ? 0.00 : point.getZ());
            }
        }
        //设置摄像头的状态,默认正常
        c.setStatus(0);
        if (StringUtils.isNotBlank(sv.getName())) {
            if (findCameraAlarm(sv.getName(), Context.getCurrentTenantId(), Context.getCurrentOrgCode()) > 0) {
                c.setStatus(1);
            }
        }
        return c;
    }



    private int findCameraAlarm(String cameraName, Long tenentId, String orgCode) {
        return alarmMessageService.findCameraAlarm(cameraName, tenentId, orgCode);
    }

    @Override
    public void delete(Long id) {
        bpProductionFacilityVideoDao.deleteById(id);
    }

    @Override
    public BpProductionFacilityVideoBean getById(Long id) {
        BpProductionFacilityVideoBean bean = new BpProductionFacilityVideoBean();
        BpProductionFacilityVideo video = bpProductionFacilityVideoDao.findById(id).get();
        BpSystemVideo bpSystemVideo = bpSystemVideoDao.findById(video.getSystemVideoId()).get();
        BeanUtils.copyProperties(video, bean);
        if (bpSystemVideo != null) {
            bean.setName(bpSystemVideo.getName());
        }
        return bean;
    }

    @Override
    public Page<BpSystemVideoAddBean> findVideoPage(Pageable pageable, Long deviceFacilityId) {
        QBpSystemVideo q = bpSystemVideo;
        Predicate predicate = null;
        if (deviceFacilityId!=null&&deviceFacilityId!=0) {
            List<Long> oldList = bpProductionFacilityVideoDao.findIdsByDeviceFacilityId(deviceFacilityId);
            if (CollectionUtils.isNotEmpty(oldList)){
                predicate = ExpressionUtils.and(predicate, q.id.notIn(oldList));
            }
        }

        Page<BpSystemVideo> videos  = predicate == null ? dao.findAll(pageable) : dao.findAll(predicate, pageable);
        return PageDataUtils.convertPageData(videos, (bpSystemVideo) -> {
            BpSystemVideoAddBean b = new BpSystemVideoAddBean();
            BeanUtils.copyProperties(bpSystemVideo, b);
            b.setDateFormat("yyyy-MM-dd");
            b.setTimeFormat("mm:HH:dd");
            b.setVideoId(b.getId());
            if (StringUtils.isNotBlank(bpSystemVideo.getEvaluation())) {
                Optional<RiskDistrict> districtOperation = riskDistrictDao.findById(new Long(bpSystemVideo.getEvaluation()));
                districtOperation.ifPresent(riskDistrict -> b.setEvaluationName(riskDistrict.getName()));
                b.setEvaluationId(bpSystemVideo.getEvaluation());
            }
            return b;
        });
    }
}
